MODULE SPPCFLSTL_MOD
CONTAINS
SUBROUTINE SPPCFLSTL(KIDIA,KFDIA,KLON &
! INPUT - trajectory
 & , PUMLEV5, PVMLEV5, PQMLEV5, PAPHMS5, PGEOMLEV5, PCPTGZLEV5 &
 & , PCPTS5 , PQSAM5 , PZ0MM5 , PZ0HM5 , PZ0QM5   , PBUOM5 &
 & , YDCST  , YDEXC &
! OUPUT - trajectory
 & , PU105  , PV105  , P10NU5 , P10NV5 , PT25   , PD25   , PQ25 &
! INPUT
 & , PUMLEV , PVMLEV , PQMLEV , PAPHMS , PGEOMLEV , PCPTGZLEV &
 & , PCPTS  , PQSAM  , PZ0MM  , PZ0HM  , PZ0QM    , PBUOM &
 ! OUPUT     
 & , PU10   , PV10   , P10NU  , P10NV  , PT2    , PD2    , PQ2 )  

USE PARKIND1 , ONLY : JPIM, JPRB, JPRD
USE YOMHOOK  , ONLY : LHOOK, DR_HOOK, JPHOOK
USE YOS_THF  , ONLY : R4LES, R2ES, R3LES, RVTMP2
USE YOS_CST  , ONLY : TCST
USE YOS_EXC  , ONLY : TEXC
! (C) Copyright 2005- ECMWF.
!
! This software is licensed under the terms of the Apache Licence Version 2.0
! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
! In applying this licence, ECMWF does not waive the privileges and immunities
! granted to it by virtue of its status as an intergovernmental organisation
! nor does it submit to any jurisdiction.


!     ------------------------------------------------------------------

!**   *SPPCFLSTL* - COMPUTES THE SURFACE (2 M) TEMPERATURE AND HUMIDITY
!                   WITH STABILITY FROM GELEYN'S INTERPOLATION
!                   (Tangent-linear)

!  AUTHOR: 
!     M. Janiskova   ECMWF  June 2005 - TL version of SPPCFLS for externalize 
!                                       SURF

!  REVISION HISTORY:
!     H. Hersbach   04-Dec-2009 10-m neutral wind

!     PURPOSE
!     -------

!     COMPUTE WIND COMPONENTS, TEMPERATURE AND DEWPOINT TEMPERATURE
!     AT SCREEN LEVEL HEIGHT
!     (Tangent linear)

!     INTERFACE
!     ---------

!     *SPPCFLSTL* IS CALLED BY *SURFPPSTL* from *VDFMAINSTL*

!     INPUT PARAMETERS (INTEGER):

!     *KIDIA*        START POINT
!     *KFDIA*        END POINT
!     *KLON*         NUMBER OF GRID POINTS PER PACKET

!*      INPUT PARAMETERS (REAL):
!  Trajectory  Perturbation  Description                               Unit
!  PUMLEV5     PUMLEV        X-VELOCITY COMPONENT AT T-1,              m/s
!                            lowest atmospheric level
!  PVMLEV5     PVMLEV        Y-VELOCITY COMPONENT AT T-1,              m/s
!                            lowest atmospheric level
!  PQMLEV5     PQMLEV        SPECIFIC HUMUDITY AT T-1,                 kg/kg
!                            lowest atmospheric level
!  PAPHMS5     PAPHMS        Surface PRESSURE AT T-1                   Pa
!  PGEOMLEV5   PGEOMLEV      GEOPOTENTIAL AT T-1,                      J/kg
!                            lowest atmospheric level
!  PCPTGZLEV5  PCPTGZLEV     DRY STATIC ENERGY AT LOWEST MODEL LEVEL   J/kg
!  PCPTS5      PCPTS         DRY STATIC ENERGY AT THE SURFACE          J/kg
!  PQSAM5      PQSAM         SPECIFIC HUMIDITY AT THE SURFACE          kg/kg
!  PZ0MM5      PZ0MM         AERODYNAMIC ROUGHNESS LENGTH              m
!  PZ0HM5      PZ0HM         ROUGHNESS LENGTH FOR TEMPERATURE          m
!  PZ0QM5      PZ0QM         ROUGHNESS LENGTH FOR MOISTURE             m
!  PBUOM5      PBUOM         BUOYANCE FLUX AT THE SURFACE              ???? 

!*      OUTPUT PARAMETERS (REAL):
!  Trajectory  Perturbation  Description                               Unit
!  PU105       PU10          U-COMPONENT WIND AT 10 M                  m/s
!  PV105       PV10          V-COMPONENT WIND AT 10 M                  m/s
!  P10NU5      P10NU         U-COMPONENT NEUTRAL WIND AT 10 M          m/s
!  P10NV5      P10NV         V-COMPONENT NEUTRAL WIND AT 10 M          m/s
!  PT25        PT2           TEMPERATURE AT 2 M                        K
!  PD25        PD2           DEW POINT TEMPERATURE AT 2 M              K
!  PQ25        PQ2           SPECIFIC HUMIDITY AT 2 M                  K


!     METHOD
!     ------

!     ANALYTIC INTERPOLATION - GELEYN (1988) TELLUS 40A 347-351

!     ------------------------------------------------------------------
!     REMARK : THE MAIN JUSTIFICATION OF THIS ROUTINE IS 
!              FOR USE IN TL AND AD VERSIONS OF IFS
!     ------------------------------------------------------------------
!
!     MODIFICATIONS
!     -------------
!
!      P. Lopez, ECMWF, October 2006 : Corrected bug in exponential.
!
!-----------------------------------------------------------------------

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN)    :: KLON 
INTEGER(KIND=JPIM),INTENT(IN)    :: KIDIA 
INTEGER(KIND=JPIM),INTENT(IN)    :: KFDIA 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PUMLEV5(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PVMLEV5(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PQMLEV5(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PAPHMS5(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGEOMLEV5(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCPTGZLEV5(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCPTS5(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PQSAM5(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PZ0MM5(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PZ0HM5(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PZ0QM5(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PBUOM5(:) 
TYPE(TCST)        ,INTENT(IN)    :: YDCST
TYPE(TEXC)        ,INTENT(IN)    :: YDEXC
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PU105(:) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PV105(:) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: P10NU5(:) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: P10NV5(:) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PT25(:) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PD25(:) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PQ25(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PUMLEV(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PVMLEV(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PQMLEV(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PAPHMS(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGEOMLEV(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCPTGZLEV(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCPTS(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PQSAM(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PZ0MM(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PZ0HM(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PZ0QM(:) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PBUOM(:) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PU10(:) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PV10(:) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: P10NU(:) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: P10NV(:) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PT2(:) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PD2(:) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PQ2(:) 

!*            LOCAL STORAGE
!             ----- -------

REAL(KIND=JPRB) :: Z1DZ0M5(KLON), Z1DZ0H5(KLON), Z1DZ0Q5(KLON), ZXLNM5(KLON)
REAL(KIND=JPRB) :: ZXLNH5(KLON) , ZXLNQ5(KLON) , ZDU25(KLON)  , ZNLEV5(KLON)
REAL(KIND=JPRB) :: Z1DZ1D5(KLON), ZRICLS5(KLON)
REAL(KIND=JPRB) :: ZCFM5(KLON)  , ZCFH5(KLON)  , ZCFQ5(KLON)
REAL(KIND=JPRB) :: ZCDNM5(KLON) , ZCDNH5(KLON) , ZCDNQ5(KLON) , ZZQM15(KLON)

REAL(KIND=JPRB) :: Z1DZ0M(KLON), Z1DZ0H(KLON), Z1DZ0Q(KLON), ZXLNM(KLON)
REAL(KIND=JPRB) :: ZXLNH(KLON) , ZXLNQ(KLON) , ZDU2(KLON)  , ZNLEV(KLON)
REAL(KIND=JPRB) :: Z1DZ1D(KLON), ZRICLS(KLON)
REAL(KIND=JPRB) :: ZCFM(KLON)  , ZCFH(KLON)  , ZCFQ(KLON)
REAL(KIND=JPRB) :: ZCDNM(KLON) , ZCDNH(KLON) , ZCDNQ(KLON) , ZZQM1(KLON)

INTEGER(KIND=JPIM) :: JL

REAL(KIND=JPRB) :: Z10UIV5  , Z10NIV5 ,  Z2QIV5, Z2SIV5,&
 & ZAPH2M5, ZBD5, ZBH5 , ZBN5  , ZBNH5 , ZBNQ5 , ZBQ5  , ZCH5  , &
 & ZCH05  , ZCM5, ZCM05, ZCORQ5, ZCORS5, &
 & ZCORU5 , ZCPT2M5, ZCQ5  , ZCQ05 , &
 & ZDRORO5, ZFRAC5 , ZLOGQ5, ZLOGS5, ZSDIV5, ZMULTI5, &
 & ZLOGU5 , ZMU5   , ZMUQ5 , ZPH5  , ZPM5  , ZPQ5   , ZRS5, ZRU5, &
 & ZWST25 , Z1EXP5, Z2EXP5, Z3EXP5, Z4EXP5 , Z5EXP5 , Z6EXP5, &
 & Z1S5   , Z2S5   , Z3S5  , Z4S5  , Z5S5  , Z6S5   , Z7S5  , Z8S5  , &
 & Z9S5   , Z9N5   , Z1T5   , Z2T5  , Z1X5  , Z2X5  , Z3X5   , Z4X5  

REAL(KIND=JPRB) :: Z10M, Z10UIV, Z10NIV , Z2B, Z2M, Z2QIV, Z2SIV, Z3B,&
 & ZAPH2M, ZBD, ZBH , ZBN  , ZBNH , ZBNQ , ZBQ  , ZCH  , &
 & ZCH0  , ZCM, ZCM0, ZCON1, ZCON2, ZCORQ, ZCORS, &
 & ZCORU , ZCPT2M, ZCQ  , ZCQ0 , ZD   , &
 & ZDRORO, ZFRAC , ZIPBL, ZLOGQ, ZLOGS, ZSDIV, ZMULTI, &
 & ZLOGU , ZMU   , ZMUQ , ZPH  , ZPM  , ZPQ  , ZRS, ZRU, &
 & ZWST2 , Z1EXP , Z2EXP, Z3EXP, Z4EXP, Z5EXP, Z6EXP, &
 & Z1S   , Z2S   , Z3S  , Z4S  , Z5S  , Z6S  , Z7S  , Z8S  , &
 & Z9S   , Z9N   , Z1T   , Z2T  , ZEPS1 
REAL(KIND=JPHOOK) :: ZHOOK_HANDLE

!     ------------------------------------------------------------------

!*       1.   INITIALIZE CONSTANTS
!             ---------- ----------

IF (LHOOK) CALL DR_HOOK('SPPCFLSTL_MOD:SPPCFLSTL',0,ZHOOK_HANDLE)
ASSOCIATE(RCPD=>YDCST%RCPD, RD=>YDCST%RD, RETV=>YDCST%RETV, RG=>YDCST%RG, &
 & RTT=>YDCST%RTT, &
 & REPDU2=>YDEXC%REPDU2, RKAP=>YDEXC%RKAP, RPARZI=>YDEXC%RPARZI)
ZCON1 = RVTMP2-RETV
ZCON2 = 2.0_JPRB/3.0_JPRB

!     CONSTANTS FOR THE STABILITY FUNCTIONS

Z2B = 10.0_JPRB
ZD  = 5.0_JPRB
Z3B = 15.0_JPRB

!     PBL HEIGHT FOR W* - EFFECT

ZIPBL = RPARZI

!     THIS SPECIFIES THE HEIGHT FOR U,V (10 M) AND T,Q (2 M)

Z10M = 10.0_JPRB
Z2M  = 2.0_JPRB
ZEPS1  =1.0E-12_JPRB

!     ------------------------------------------------------------------

!*       2.   COMPUTATION OF SURFACE EXCHANGE COEFFICIENTS
!             ---------------------------------------------

DO JL=KIDIA,KFDIA

!             (W*)**2, WIND SHEAR, RICHARDSON NUMBER,

  IF (PBUOM5(JL)  <  ZEPS1) THEN
    ZWST2  = 0.0_JPRB
    ZWST25 = 0.0_JPRB
  ELSE
    ZWST2  = ZIPBL*ZCON2*((PBUOM5(JL)*ZIPBL)**(ZCON2-1))*PBUOM(JL)
    ZWST25 = (PBUOM5(JL)*ZIPBL)**ZCON2
  ENDIF
  Z1S  = 2.0_JPRB*(PUMLEV(JL)*PUMLEV5(JL)+PVMLEV(JL)*PVMLEV5(JL))+ZWST2
  Z1S5 = PUMLEV5(JL)**2+PVMLEV5(JL)**2+ZWST25
  IF (Z1S5 < REPDU2) THEN
    ZDU2 (JL) = 0.0_JPRB
    ZDU25(JL) = REPDU2
  ELSE
    ZDU2 (JL) = Z1S
    ZDU25(JL) = Z1S5
  ENDIF
  Z2S  = PCPTGZLEV(JL)+PCPTS(JL)-PGEOMLEV(JL)
  Z2S5 = PCPTGZLEV5(JL)+PCPTS5(JL)-PGEOMLEV5(JL)
  ZDRORO  = 2.0_JPRB*(PCPTGZLEV(JL)-PCPTS(JL))/Z2S5 &
   & -2.0_JPRB*(PCPTGZLEV5(JL)-PCPTS5(JL))*Z2S/Z2S5**2 &
   & -ZCON1*(PQMLEV(JL)-PQSAM(JL))
  ZDRORO5 = 2.0_JPRB*(PCPTGZLEV5(JL)-PCPTS5(JL))/Z2S5 &
   & -ZCON1*(PQMLEV5(JL)-PQSAM5(JL)) 
  ZRICLS (JL) = (PGEOMLEV5(JL)*ZDRORO+ZDRORO5*PGEOMLEV(JL))/ZDU25(JL) &
   & -PGEOMLEV5(JL)*ZDRORO5*ZDU2(JL)/ZDU25(JL)**2
  ZRICLS5(JL)=PGEOMLEV5(JL)*ZDRORO5/ZDU25(JL)


!             COMMON FACTORS IN NEUTRAL FORMULAE AND
!             DRAG COEFFICIENTS.

  ZNLEV (JL) = PGEOMLEV(JL)/RG+PZ0MM(JL)
  ZNLEV5(JL) = PGEOMLEV5(JL)/RG+PZ0MM5(JL)
  Z1DZ0M (JL) = ZNLEV(JL)/PZ0MM5(JL) - ZNLEV5(JL)*PZ0MM(JL)/PZ0MM5(JL)**2
  Z1DZ0M5(JL) = ZNLEV5(JL)/PZ0MM5(JL)
  Z1DZ0H (JL) = ZNLEV(JL)/PZ0HM5(JL) - ZNLEV5(JL)*PZ0HM(JL)/PZ0HM5(JL)**2
  Z1DZ0H5(JL) = ZNLEV5(JL)/PZ0HM5(JL)
  Z1DZ0Q (JL) = ZNLEV(JL)/PZ0QM5(JL) - ZNLEV5(JL)*PZ0QM(JL)/PZ0QM5(JL)**2
  Z1DZ0Q5(JL) = ZNLEV5(JL)/PZ0QM5(JL)
  Z1DZ1D (JL) = -Z1DZ0M(JL)/(Z1DZ0M5(JL)-1.0_JPRB)**2
  Z1DZ1D5(JL) = Z1DZ0M5(JL)/(Z1DZ0M5(JL)-1.0_JPRB)
  ZXLNM (JL) = Z1DZ0M(JL)/Z1DZ0M5(JL)
  ZXLNM5(JL) = LOG(Z1DZ0M5(JL))
  ZXLNH (JL) = Z1DZ0H(JL)/Z1DZ0H5(JL)
  ZXLNH5(JL) = LOG(Z1DZ0H5(JL))
  ZXLNQ (JL) = Z1DZ0Q(JL)/Z1DZ0Q5(JL)
  ZXLNQ5(JL) = LOG(Z1DZ0Q5(JL))

!              NEUTRAL DRAG COEFFICIENTS

  ZCDNH (JL) = -(RKAP**2)*(ZXLNM5(JL)*ZXLNH(JL)+ZXLNH5(JL)*ZXLNM(JL)) &
   & /(ZXLNM5(JL)*ZXLNH5(JL))**2 
  ZCDNH5(JL) = (RKAP**2)/(ZXLNM5(JL)*ZXLNH5(JL))
  ZCDNQ (JL) = -(RKAP**2)*(ZXLNM5(JL)*ZXLNQ(JL)+ZXLNQ5(JL)*ZXLNM(JL)) &
   & /(ZXLNM5(JL)*ZXLNQ5(JL))**2
  ZCDNQ5(JL) = (RKAP**2)/(ZXLNM5(JL)*ZXLNQ5(JL))
  ZCDNM (JL) = -2.0_JPRB*(RKAP**2)*ZXLNM5(JL)*ZXLNM(JL) &
   & /(ZXLNM5(JL)*ZXLNM5(JL))**2
  ZCDNM5(JL) = (RKAP**2)/(ZXLNM5(JL)*ZXLNM5(JL))

!          PARAMETERS DEPENDING ON RATIO OF ROUGHNESS LENGTHS

  Z3S  = PZ0MM(JL)/PZ0HM5(JL)-PZ0MM5(JL)*PZ0HM(JL)/PZ0HM5(JL)**2
  Z3S5 = PZ0MM5(JL)/PZ0HM5(JL)
  IF (Z3S5 > 100.0_JPRB) THEN
    ZMU  = 0.0_JPRB
    ZMU5 = LOG(100.0_JPRB)
  ELSE
    ZMU  = Z3S/Z3S5
    ZMU5 = LOG(Z3S5)
  ENDIF
  Z4S  = PZ0MM(JL)/PZ0QM5(JL)-PZ0MM5(JL)*PZ0QM(JL)/PZ0QM5(JL)**2
  Z4S5 = PZ0MM5(JL)/PZ0QM5(JL)
  IF (Z4S5 > 100.0_JPRB) THEN
    ZMUQ  = 0.0_JPRB
    ZMUQ5 = LOG(100.0_JPRB)
  ELSE
    ZMUQ  = Z4S/Z4S5
    ZMUQ5 = LOG(Z4S5)
  ENDIF

  ZCM0  = ZMU*( 2.6933_JPRB + ZMU5*(-0.7202_JPRB + 0.0462*ZMU5))
  ZCM05 = (6.8741_JPRB + ZMU5*( 2.6933_JPRB + ZMU5*(-0.3601_JPRB &
   & + ZMU5 * 0.0154_JPRB)))  
  ZPM  = ZMU*(-0.0815_JPRB + ZMU5*(0.027_JPRB + (-0.003_JPRB)*ZMU5))
  ZPM5 = (0.5233_JPRB + ZMU5*(-0.0815_JPRB + ZMU5*( 0.0135_JPRB &
   & + ZMU5 *(-0.001_JPRB))))  
  ZCH0  = ZMU*( 4.3431_JPRB + ZMU5*(1.072_JPRB + (-0.2343_JPRB)*ZMU5))
  ZCH05 = (3.2165_JPRB + ZMU5*( 4.3431_JPRB + ZMU5*( 0.5360_JPRB &
   & + ZMU5 *(-0.0781_JPRB))))  
  ZPH  = ZMU*(-0.1571_JPRB + ZMU5*(0.0654_JPRB + (-0.0078_JPRB)*ZMU5))
  ZPH5 = (0.5802_JPRB + ZMU5*(-0.1571_JPRB + ZMU5*( 0.0327_JPRB &
   & + ZMU5 *(-0.0026_JPRB))))  
  ZCQ0  = ZMUQ*( 4.3431_JPRB + ZMUQ5*(1.072_JPRB + (-0.2343_JPRB)*ZMUQ5))
  ZCQ05 = (3.2165_JPRB + ZMUQ5*( 4.3431_JPRB + ZMUQ5*(0.5360_JPRB &
   & + ZMUQ5 *(-0.0781_JPRB))))  
  ZPQ  = ZMUQ*(-0.1571_JPRB + ZMUQ5*(0.0654_JPRB + (-0.0078_JPRB)*ZMUQ5))
  ZPQ5 = (0.5802_JPRB + ZMUQ5*(-0.1571_JPRB + ZMUQ5*(0.0327_JPRB &
   & + ZMUQ5 *(-0.0026_JPRB))))  

  ZCM  = (Z1DZ0M5(JL)**ZPM5)*ZCM0 &
   & + ZCM05*ZPM5*(Z1DZ0M5(JL)**(ZPM5-1))*Z1DZ0M(JL) &
   & + ZCM05*(Z1DZ0M5(JL)**ZPM5)*LOG(Z1DZ0M5(JL))*ZPM
  ZCM5 = ZCM05*Z1DZ0M5(JL)**ZPM5
  ZCH  = (Z1DZ0H5(JL)**ZPH5)*ZCH0 &
   & + ZCH05*ZPH5*(Z1DZ0H5(JL)**(ZPH5-1))*Z1DZ0H(JL) &
   & + ZCH05*(Z1DZ0H5(JL)**ZPH5)*LOG(Z1DZ0H5(JL))*ZPH
  ZCH5 = ZCH05*Z1DZ0H5(JL)**ZPH5
  ZCQ  = (Z1DZ0Q5(JL)**ZPQ5)*ZCQ0 &
   & + ZCQ05*ZPQ5*(Z1DZ0Q5(JL)**(ZPQ5-1))*Z1DZ0Q(JL) &
   & + ZCQ05*(Z1DZ0Q5(JL)**ZPQ5)*LOG(Z1DZ0Q5(JL))*ZPQ
  ZCQ5 = ZCQ05*Z1DZ0Q5(JL)**ZPQ5

!            STABILITY FUNCTIONS 

  IF (ZRICLS5(JL) > 0.0_JPRB) THEN
    Z5S5 = SQRT(1.0_JPRB+ZD*ZRICLS5(JL))
    Z5S  = 0.5_JPRB*ZD*ZRICLS(JL)/Z5S5
    ZSDIV  = Z2B*ZRICLS(JL)/Z5S5-Z2B*ZRICLS5(JL)*Z5S/Z5S5**2
    ZSDIV5 = 1.0_JPRB+Z2B*ZRICLS5(JL)/Z5S5
    ZMULTI = -Z3B*(ZRICLS5(JL)*Z5S+Z5S5*ZRICLS(JL)) &
     & / (1.0_JPRB+Z3B*ZRICLS5(JL)*Z5S5)**2
    ZMULTI5 = 1.0_JPRB/(1.0_JPRB+Z3B*ZRICLS5(JL)*Z5S5)

    ZCFM (JL) = ZCDNM(JL)/ZSDIV5-ZCDNM5(JL)*ZSDIV/ZSDIV5**2
    ZCFM5(JL) = ZCDNM5(JL)/ZSDIV5
    ZCFH (JL) = ZCDNH5(JL)*ZMULTI+ZMULTI5*ZCDNH(JL)
    ZCFH5(JL) = ZCDNH5(JL)*ZMULTI5
    ZCFQ (JL) = ZCDNQ5(JL)*ZMULTI+ZMULTI5*ZCDNQ(JL)
    ZCFQ5(JL) = ZCDNQ5(JL)*ZMULTI5
  ELSE
    IF (ZRICLS5(JL) < 0.0_JPRB) THEN
      Z6S5 = SQRT(-ZRICLS5(JL))
      Z6S  = -0.5_JPRB*ZRICLS(JL)/Z6S5
    ELSE
      Z6S5 = SQRT(ZRICLS5(JL))
      Z6S  = 0.5_JPRB*ZRICLS(JL)/Z6S5
    ENDIF

    Z1X5 = 1.0_JPRB/(1.0_JPRB+Z3B*ZCDNM5(JL)*ZCM5*Z6S5)
    ZCFM (JL) = (1.0_JPRB-Z2B*ZRICLS5(JL)*Z1X5)*ZCDNM(JL) &
     & - Z2B*ZCDNM5(JL)*Z1X5*ZRICLS(JL) &
     & + Z2B*Z3B*ZRICLS5(JL)*ZCDNM5(JL)*(Z1X5**2) &
     & * (ZCDNM(JL)*ZCM5*Z6S5+ZCDNM5(JL)*ZCM*Z6S5+ZCDNM5(JL)*ZCM5*Z6S)
    ZCFM5(JL) = ZCDNM5(JL)*(1.0_JPRB-Z2B*ZRICLS5(JL)*Z1X5)

    Z2X5 = 1.0_JPRB/(1.0_JPRB+Z3B*ZCDNH5(JL)*ZCH5*Z6S5)
    ZCFH (JL) = (1.0_JPRB-Z3B*ZRICLS5(JL)*Z2X5)*ZCDNH(JL) &
     & - Z3B*ZCDNH5(JL)*Z2X5*ZRICLS(JL) &
     & + Z3B*Z3B*ZRICLS5(JL)*ZCDNH5(JL)*(Z2X5**2) &
     & * (ZCDNH(JL)*ZCH5*Z6S5+ZCDNH5(JL)*ZCH*Z6S5+ZCDNH5(JL)*ZCH5*Z6S)
    ZCFH5(JL) = ZCDNH5(JL)*(1.0_JPRB-Z3B*ZRICLS5(JL)*Z2X5)

    Z3X5 = 1.0_JPRB/(1.0_JPRB+Z3B*ZCDNQ5(JL)*ZCQ5*Z6S5) 
    ZCFQ (JL) = (1.0_JPRB-Z3B*ZRICLS5(JL)*Z3X5)*ZCDNQ(JL) &
     & - Z3B*ZCDNQ5(JL)*Z3X5*ZRICLS(JL) &
     & + Z3B*Z3B*ZRICLS5(JL)*ZCDNQ5(JL)*(Z3X5**2) &
     & * (ZCDNQ(JL)*ZCQ5*Z6S5+ZCDNQ5(JL)*ZCQ*Z6S5+ZCDNQ5(JL)*ZCQ5*Z6S)
    ZCFQ5(JL) = ZCDNQ5(JL)*(1.0_JPRB-Z3B*ZRICLS5(JL)*Z3X5)
  ENDIF

ENDDO

!     ------------------------------------------------------------------

!*       3.   COMPUTATION OF WIND COMPONENT AND TEMPERATURE
!             ----------------------------------------------

DO JL=KIDIA,KFDIA
  Z7S5 = SQRT(ZCDNM5(JL))
  Z7S  = 0.5*ZCDNM(JL)/Z7S5
  ZBN  = -RKAP*Z7S/Z7S5**2
  ZBN5 = RKAP/Z7S5
  ZBNH  = RKAP*Z7S/ZCDNH5(JL)-RKAP*Z7S5*ZCDNH(JL)/ZCDNH5(JL)**2
  ZBNH5 = RKAP*Z7S5/ZCDNH5(JL)
  ZBNQ  = RKAP*Z7S/ZCDNQ5(JL)-RKAP*Z7S5*ZCDNQ(JL)/ZCDNQ5(JL)**2
  ZBNQ5 = RKAP*Z7S5/ZCDNQ5(JL)
  Z8S5 = SQRT(ZCFM5(JL))
  Z8S  = 0.5*ZCFM(JL)/Z8S5
  ZBD  = -RKAP*Z8S/Z8S5**2
  ZBD5 = RKAP/Z8S5
  ZBH  = RKAP*Z8S/ZCFH5(JL)-RKAP*Z8S5*ZCFH(JL)/ZCFH5(JL)**2
  ZBH5 = RKAP*Z8S5/ZCFH5(JL)
  ZBQ  = RKAP*Z8S/ZCFQ5(JL)-RKAP*Z8S5*ZCFQ(JL)/ZCFQ5(JL)**2
  ZBQ5 = RKAP*Z8S5/ZCFQ5(JL)

  ZRU  = -Z10M*ZNLEV(JL)/ZNLEV5(JL)**2
  ZRU5 = Z10M/ZNLEV5(JL)
  ZRS  = -Z2M*ZNLEV(JL)/ZNLEV5(JL)**2
  ZRS5 = Z2M/ZNLEV5(JL)

  Z1EXP5 = EXP(ZBN5)
  Z1EXP  = Z1EXP5*ZBN
  ZLOGU  = (ZRU*(Z1EXP5-1.0_JPRB)+ZRU5*Z1EXP) &
   & / (1.0_JPRB+ZRU5*(Z1EXP5-1.0_JPRB))
  ZLOGU5 = LOG(1.0_JPRB+ZRU5*(Z1EXP5-1.0_JPRB))
  Z2EXP5 = EXP(ZBNH5)
  Z2EXP  = Z2EXP5*ZBNH
  ZLOGS  = (ZRS*(Z2EXP5-1.0_JPRB)+ZRS5*Z2EXP) &
   & / (1.0_JPRB+ZRS5*(Z2EXP5-1.0_JPRB))
  ZLOGS5 = LOG(1.0_JPRB+ZRS5*(Z2EXP5-1.0_JPRB))
  Z3EXP5 = EXP(ZBNQ5)
  Z3EXP  = Z3EXP5*ZBNQ
  ZLOGQ  = (ZRS*(Z3EXP5-1.0_JPRB)+ZRS5*Z3EXP) &
   & / (1.0_JPRB+ZRS5*(Z3EXP5-1.0_JPRB))
  ZLOGQ5 = LOG(1.0_JPRB+ZRS5*(Z3EXP5-1.0_JPRB))

  IF (ZRICLS5(JL) > 0.0_JPRB) THEN
    ZCORU  = (ZBN5-ZBD5)*ZRU+ZRU5*(ZBN-ZBD)
    ZCORU5 = ZRU5*(ZBN5-ZBD5)
    ZCORS  = (ZBNH5-ZBH5)*ZRS+ZRS5*(ZBNH-ZBH)
    ZCORS5 = ZRS5*(ZBNH5-ZBH5)
    ZCORQ  = (ZBNQ5-ZBQ5)*ZRS+ZRS5*(ZBNQ-ZBQ)
    ZCORQ5 = ZRS5*(ZBNQ5-ZBQ5)
  ELSE
    IF ((ZBN5 -ZBD5) < 0.0_JPRB) THEN
      Z4EXP  = 0.0_JPRB
      Z4EXP5 = 1.0_JPRB
    ELSE
      IF ((ZBN5-ZBD5) < 200.0_JPRB) THEN
        Z4EXP5 = EXP(ZBN5-ZBD5)
        Z4EXP  = Z4EXP5*(ZBN -ZBD)
      ELSE
        Z4EXP5 = EXP(200.0_JPRD)
        Z4EXP  = 0.0_JPRB
      ENDIF
    ENDIF
    ZCORU  = ((Z4EXP5-1.0_JPRB)*ZRU+ZRU5*Z4EXP) &
     & / (1.0_JPRB+ZRU5*(Z4EXP5-1.0_JPRB))
    ZCORU5 = LOG(1.0_JPRB+ZRU5*(Z4EXP5-1.0_JPRB))

    IF ((ZBNH5-ZBH5) < 0.0_JPRB) THEN
      Z5EXP  = 0.0_JPRB
      Z5EXP5 = 1.0_JPRB
    ELSE
      IF ((ZBNH5-ZBH5) < 200.0_JPRB) THEN
        Z5EXP5 = EXP(ZBNH5-ZBH5)
        Z5EXP  = Z5EXP5*(ZBNH -ZBH)
      ELSE
        Z5EXP5 = EXP(200.0_JPRD)
        Z5EXP  = 0.0_JPRB
      ENDIF
    ENDIF
    ZCORS  = ((Z5EXP5-1.0_JPRB)*ZRS+ZRS5*Z5EXP) &
     & / (1.0_JPRB+ZRS5*(Z5EXP5-1.0_JPRB))
    ZCORS5 = LOG(1.0_JPRB+ZRS5*(Z5EXP5-1.0_JPRB))

    IF ((ZBNQ5-ZBQ5) < 0.0_JPRB) THEN
      Z6EXP  = 0.0_JPRB
      Z6EXP5 = 1.0_JPRB
    ELSE
      IF ((ZBNQ5-ZBQ5) < 200.0_JPRB) THEN
        Z6EXP5 = EXP(ZBNQ5-ZBQ5)
        Z6EXP  = Z6EXP5*(ZBNQ -ZBQ)
      ELSE
        Z6EXP5 = EXP(200.0_JPRD)
        Z6EXP  = 0.0_JPRB
      ENDIF
    ENDIF
    ZCORQ  = ((Z6EXP5-1.0_JPRB)*ZRS+ZRS5*Z6EXP) &
     & / (1.0_JPRB+ZRS5*(Z6EXP5-1.0_JPRB))
    ZCORQ5 = LOG(1.0_JPRB+ZRS5*(Z6EXP5-1.0_JPRB))
  ENDIF

!     10 M WIND COMPONENT

  Z9S  = (ZLOGU-ZCORU)/ZBD5-(ZLOGU5-ZCORU5)*ZBD/ZBD5**2
  Z9S5 = (ZLOGU5-ZCORU5)/ZBD5
  IF (Z9S5 > 1.0_JPRB) THEN
    Z10UIV  = 0.0_JPRB
    Z10UIV5 = 1.0_JPRB
  ELSEIF (Z9S5 < 0.0_JPRB) THEN
    Z10UIV  = 0.0_JPRB
    Z10UIV5 = 0.0_JPRB
  ELSE
    Z10UIV  = Z9S
    Z10UIV5 = Z9S5
  ENDIF

  PU10 (JL) = PUMLEV5(JL)*Z10UIV+Z10UIV5*PUMLEV(JL)
  PU105(JL) = PUMLEV5(JL)*Z10UIV5
  PV10 (JL) = PVMLEV5(JL)*Z10UIV+Z10UIV5*PVMLEV(JL)
  PV105(JL) = PVMLEV5(JL)*Z10UIV5

!     10 M NEUTRAL WIND COMPONENT

  Z9N  = ZLOGU/ZBD5-ZLOGU5*ZBD/ZBD5**2
  Z9N5 = ZLOGU5/ZBD5
  IF (Z9N5 < 0.0_JPRB) THEN
    Z10NIV  = 0.0_JPRB
    Z10NIV5 = 0.0_JPRB
  ELSE
    Z10NIV  = Z9N
    Z10NIV5 = Z9N5
  ENDIF

  P10NU (JL) = PUMLEV5(JL)*Z10NIV+Z10NIV5*PUMLEV(JL)
  P10NU5(JL) = PUMLEV5(JL)*Z10NIV5
  P10NV (JL) = PVMLEV5(JL)*Z10NIV+Z10NIV5*PVMLEV(JL)
  P10NV5(JL) = PVMLEV5(JL)*Z10NIV5

!     2M TEMPERATURE AND 2M SPECIFIC HUMIDITY

  Z1T  = (ZLOGS-ZCORS)/ZBH5-(ZLOGS5-ZCORS5)*ZBH/ZBH5**2
  Z1T5 = (ZLOGS5-ZCORS5)/ZBH5
  IF (Z1T5 > 1.0_JPRB) THEN
    Z2SIV  = 0.0_JPRB
    Z2SIV5 = 1.0_JPRB
  ELSEIF (Z1T5 < 0.0_JPRB) THEN
    Z2SIV  = 0.0_JPRB
    Z2SIV5 = 0.0_JPRB
  ELSE
    Z2SIV  = Z1T
    Z2SIV5 = Z1T5
  ENDIF
  
  Z2T  = (ZLOGQ-ZCORQ)/ZBQ5-(ZLOGQ5-ZCORQ5)*ZBQ/ZBQ5**2
  Z2T5 = (ZLOGQ5-ZCORQ5)/ZBQ5
  IF (Z2T5 > 1.0_JPRB) THEN
    Z2QIV  = 0.0_JPRB
    Z2QIV5 = 1.0_JPRB
  ELSEIF (Z2T5 < 0.0_JPRB) THEN
    Z2QIV  = 0.0_JPRB
    Z2QIV5 = 0.0_JPRB
  ELSE
    Z2QIV  = Z2T
    Z2QIV5 = Z2T5
  ENDIF

  ZCPT2M  = PCPTS(JL)+(PCPTGZLEV5(JL)-PCPTS5(JL))*Z2SIV &
   & + Z2SIV5*(PCPTGZLEV(JL)-PCPTS(JL))
  ZCPT2M5 = PCPTS5(JL)+(PCPTGZLEV5(JL)-PCPTS5(JL))*Z2SIV5

  IF (PQMLEV5(JL) < 1.E-12_JPRB) THEN
    ZZQM1 (JL)  = 0.0_JPRB
    ZZQM15(JL) = 1.E-12_JPRB
  ELSE
    ZZQM1 (JL) = PQMLEV(JL)
    ZZQM15(JL) = PQMLEV5(JL)
  ENDIF
  PQ2 (JL) = PQSAM(JL)+(ZZQM15(JL)-PQSAM5(JL))*Z2QIV &
   & + Z2QIV5*(ZZQM1(JL)-PQSAM(JL))
  PQ25(JL) = PQSAM5(JL)+(ZZQM15(JL)-PQSAM5(JL))*Z2QIV5

!     APPROXIMATE MOISTURE CORRECTION IN CP WITH QNLEV

  PT2 (JL) = ZCPT2M/( RCPD*(1.0_JPRB+RVTMP2*ZZQM15(JL)) ) &
   & - (ZCPT2M5-RG*Z2M)*RVTMP2*ZZQM1(JL) &
   & / ( RCPD*(1.0_JPRB+RVTMP2*ZZQM15(JL))**2 )
  PT25(JL) = (ZCPT2M5-RG*Z2M)/( RCPD*(1.0_JPRB+RVTMP2*ZZQM15(JL)) )

ENDDO

!     ------------------------------------------------------------------

!        4.   COMPUTE  DEW POINT TEMPERATURE
!             ------------------------------

DO JL=KIDIA,KFDIA
  Z4X5 = 1.0_JPRB/(RD*PT25(JL)*(1.0_JPRB+RETV*ZZQM15(JL)))
  ZAPH2M  = (1.0_JPRB-Z2M*Z4X5)*PAPHMS(JL) &
   & + Z2M*RD*PAPHMS5(JL)*(Z4X5**2) &
   & * ((1.0_JPRB+RETV*ZZQM15(JL))*PT2(JL)+RETV*PT25(JL)*ZZQM1(JL))
  ZAPH2M5 = PAPHMS5(JL)*(1.0_JPRB-Z2M*Z4X5) 

! Note the use of saturation with respect to water in conformance to WMO
!  observation dissemination practice

  ZFRAC  = (ZAPH2M5*PQ2(JL)+PQ25(JL)*(1.0_JPRB+RETV*PQ25(JL))*ZAPH2M) &
   & / (R3LES*ZAPH2M5*PQ25(JL)*(1.0_JPRB+RETV*PQ25(JL)))
  ZFRAC5 = LOG(ZAPH2M5*PQ25(JL)/(R2ES*(1.0_JPRB+RETV*PQ25(JL))))/R3LES
  PD2 (JL) = (RTT-R4LES)*ZFRAC/(1.0_JPRB-ZFRAC5)**2
  PD25(JL) = (RTT-ZFRAC5*R4LES)/(1.0_JPRB-ZFRAC5)

!     LIMIT DEW POINT TEMPERATURE < TEMPERATURE

  IF (PD25(JL) > PT25(JL)) THEN
    PD2 (JL) = PT2 (JL)
    PD25(JL) = PT25(JL)
  ENDIF

ENDDO

END ASSOCIATE
IF (LHOOK) CALL DR_HOOK('SPPCFLSTL_MOD:SPPCFLSTL',1,ZHOOK_HANDLE)
END SUBROUTINE SPPCFLSTL
END MODULE SPPCFLSTL_MOD
